import { fileURLToPath } from 'url'; // 文件路径转换
import { defineConfig, loadEnv } from 'vite'; // vite 配置文件
import type { UserConfig, ConfigEnv } from 'vite'; // vite 配置文件类型
import vue from '@vitejs/plugin-vue'; // vue文件编译插件
import vueJsx from '@vitejs/plugin-vue-jsx'; // jsx文件编译插件
import VueDevTools from 'vite-plugin-vue-devtools'; // vue-devtools
import AutoImport from 'unplugin-auto-import/vite'; // 自动引入插件
import Components from 'unplugin-vue-components/vite'; // 自动引入组件插件
import ElementPlus from 'unplugin-element-plus/vite'; // 自动引入ElementPlus
import Icons from 'unplugin-icons/vite'; // 自动引入图标插件
import IconsResolver from 'unplugin-icons/resolver'; // 自动引入图标解析器
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; // 自动引入ElementPlus解析器
import { viteMockServe } from 'vite-plugin-mock'; // mock插件
import { visualizer } from 'rollup-plugin-visualizer'; // 打包分析插件
import externalGlobals from 'rollup-plugin-external-globals'; // 自动引入外部库
import ViteCompression from 'vite-plugin-compression'; // gzip 压缩
import { createHtmlPlugin } from 'vite-plugin-html'; // html 模板插件

const globals = externalGlobals({
  echart: 'echart'
});

export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  // 获取当前工作目录
  const root = process.cwd();
  // 获取环境变量
  const env = loadEnv(mode, root);
  return {
    // 项目根目录
    root,
    // 项目部署的基础路径
    base: './',
    publicDir: fileURLToPath(new URL('./public', import.meta.url)), // 无需处理的静态资源位置
    assetsInclude: fileURLToPath(new URL('./src/assets', import.meta.url)), // 需要处理的静态资源位置
    plugins: [
      // Vue模板文件编译插件
      vue(),
      // jsx文件编译插件
      vueJsx(),
      // mock插件
      viteMockServe({
        // 如果接口为 /mock/xxx 以 mock 开头就会被拦截响应配置的内容
        mockPath: 'mock', // 数据模拟需要拦截的请求起始 URL
        enable: true // 本地环境是否开启 mock 功能
      }),
      // 开启 ElementPlus 自动引入CSS
      ElementPlus({}),
      // 自动引入组件及 ICON
      AutoImport({
        resolvers: [IconsResolver(), ElementPlusResolver()],
        imports: ['vue', 'vue-router'],
        dts: fileURLToPath(new URL('./types/auto-imports.d.ts', import.meta.url)),
        // 解决 eslint 报错问题
        eslintrc: {
          // 更新 .eslintrc-auto-import.json 文件 需要将 enabled 设置为 true, 更新完后设置为 false
          enabled: false,
          filepath: fileURLToPath(new URL('./.eslintrc-auto-import.json', import.meta.url)), // 生成的文件路径
          globalsPropValue: true
        }
      }),
      // 自动注册组件
      Components({
        resolvers: [IconsResolver(), ElementPlusResolver()],
        dts: fileURLToPath(new URL('./types/components.d.ts', import.meta.url))
      }),
      // 自动安装图标
      Icons({
        autoInstall: true
      }),
      // 开启VueDevTools
      VueDevTools(),
      // 打包压缩
      ViteCompression({
        threshold: 1024 * 20,
        algorithm: 'gzip',
        ext: '.gz'
      }),
      // 打包时自动注入外链
      createHtmlPlugin({
        inject: {
          data: {
            title: 'Vite + Vue3 + TS + Pinia + ElementPlus',
            echartscript: '<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js"></script>'
          }
        }
      })
    ],
    // 运行后本地预览的服务器
    server: {
      // 是否开启https
      // https: {},
      // 指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址，包括局域网和公网地址。
      host: true,
      // 开发环境预览服务器端口
      port: 9000,
      // 启动后是否自动打开浏览器
      open: false,
      // 是否开启CORS跨域
      cors: true,
      // 代理服务器
      proxy: {
        // 这里的意思是 以/api开头发送的请求都会被转发到 http://xxx:9000
        [env.VITE_APP_API_BASEURL]: {
          target: 'http://localhost:9000',
          // 改变 Host Header
          changeOrigin: true
          // 发起请求时将 '/api' 替换为 ''
          //rewrite: (path) => path.replace(/^\/api/, ""),
        },
        [env.VITE_APP_MOCK_BASEURL]: {
          target: 'http://localhost:9000',
          // 改变 Host Header
          changeOrigin: true
          // 发起请求时将 '/api' 替换为 ''
          //rewrite: (path) => path.replace(/^\/api/, ""),
        }
      }
    },
    // 打包配置
    build: {
      // 关闭 sorcemap 报错不会映射到源码
      sourcemap: false,
      // 打包大小超出 400kb 提示警告
      chunkSizeWarningLimit: 400,
      rollupOptions: {
        // rollup 配置
        external: ['echart'], // 需要排除打包的依赖
        plugins: [visualizer(), globals],
        input: {
          // 入口文件
          index: fileURLToPath(new URL('./index.html', import.meta.url))
        },
        // 静态资源分类打包
        // experimentalLogSideEffects: true, // 识别模块中的副作用
        treeshake: {
          // tree-shaking 配置
          preset: 'recommended'
        },
        output: {
          // 输出配置
          experimentalMinChunkSize: 20 * 1024, // 单位 b
          manualChunks: (id: string) => {
            if (id.includes('node_modules')) {
              return 'vendor';
            }
            // return 'index';
          },
          format: 'esm',
          chunkFileNames: 'static/js/chunk-[hash].js', // 拆分后的文件名
          entryFileNames: 'static/js/entry-[hash].js', // 入口文件名
          assetFileNames: 'static/[ext]/[name]-[hash].[ext]' // 静态资源文件名
        }
      }
    },
    // 配置别名
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
        '#': fileURLToPath(new URL('./types', import.meta.url))
      }
    },
    // css 配置
    css: {
      preprocessorOptions: {
        less: {
          additionalData: `@import "@/styles/variables.less";`
        }
      }
    }
  };
});
